package com.example.demo;

import org.junit.jupiter.api.Test;

public class MaxProfit {

    /**
     * 买卖股票的最佳时机一
     */
    public int maxProfit10(int[] prices) {
        int maxProfit = 0;
        int minPrice = prices[0];

        for (int i = 1; i < prices.length; i++) {
            if (prices[i] < minPrice) {
                minPrice = prices[i];
            } else if (prices[i] - minPrice > maxProfit) {
                maxProfit = prices[i] - minPrice;
            }
        }

        return maxProfit;
    }

    /**
     * 买卖股票的最佳时机一
     */
    public int maxProfit11(int[] prices) {
        int maxProfit = 0;
        int minPrice = prices[0];

        for (int i = 1; i < prices.length; i++) {
            if (prices[i] < minPrice) {
                minPrice = prices[i]; // 更新最小价格
            } else {
                maxProfit = Math.max(maxProfit, prices[i] - minPrice); // 更新最大利润
            }
        }

        return maxProfit;
    }

    /**
     * 买卖股票的最佳时机二，同一天可以高价卖出再低价买入
     * https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/description/?envType=study-plan-v2&envId=top-interview-150
     */
    public int maxProfit2(int[] prices) {
        int sum = 0;
        int prePrice = prices[0];

        for (int i = 1; i < prices.length; i++) {
            if (prices[i] - prePrice > 0) {
                sum = sum + prices[i] - prePrice;
            }
            prePrice = prices[i]; // 同一天可以高价卖出再低价买入
        }

        return sum;
    }

    @Test
    public void test() {
        int[] array = {8, 9, 3, 5, 1, 3};
        System.out.println(maxProfit3(array));
    }

    /**
     * 买卖股票的最佳时机三，同一天不能卖出再买入，难
     */
    public int maxProfit3(int[] prices) {
        int buy1 = -prices[0];
        int sell1 = 0;
        int buy2 = -prices[0];
        int sell2 = 0;

        for (int i = 1; i < prices.length; i++) {
            int price = prices[i];
            buy1 = Math.max(buy1, -price);
            sell1 = Math.max(sell1, buy1 + price);
            buy2 = Math.max(buy2, sell1 - price);
            sell2 = Math.max(sell2, buy2 + price);
        }
        return sell2;
    }
}
